package com.litchishell.ssmdemo.jdbc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author LitchiShell
 * @description:
 * @create 2022-04-17
 */
@Service
public class AccountDaoImpl implements AccountDao{

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int addAccount(Account account) {
        // 定义sql
        String sql = "insert into account(username, balance) values(?, ?)";
        // 定义数组存储sql要传递的参数
        Object[] params = new Object[] {
                account.getUsername(),
                account.getBalance()
        };
        // 执行添加操作
        return this.jdbcTemplate.update(sql, params);
    }

    @Override
    public int updateAccount(Account account) {
        // 定义sql
        String sql = "update account set username = ?, balance = ? where id = ?";
        // 定义数组存储sql要传递的参数
        Object[] params = new Object[] {
                account.getId(),
                account.getUsername(),
                account.getBalance()
        };
        // 执行更新操作
        return this.jdbcTemplate.update(sql, params);
    }

    @Override
    public int deleteAccount(int id) {
        // 定义sql
        String sql = "delete from account where id = ?";
        // 执行更新操作
        return this.jdbcTemplate.update(sql, id);
    }

    @Override
    public Account selectAccountById(int id) {
        // 定义sql
        String sql = "select * from account where id = ?";
        // 创建一个新的BeanPropertyRowMapper对象
        RowMapper<Account> rowMapper = new BeanPropertyRowMapper<>(Account.class);
        // 将id绑定到sql语句中，并通过RowMapper返回一个Object类型的单行记录
        return this.jdbcTemplate.queryForObject(sql, rowMapper, id);
    }

    @Override
    public List<Account> selectAccounts() {
        // 定义sql语句
        String sql = "select * from account";
        // 创建一个新的BeanPropertyRowMapper对象
        RowMapper<Account> rowMapper = new BeanPropertyRowMapper<>(Account.class);
        // 将id绑定到sql语句中，并通过RowMapper返回一个Object类型的单行记录
        return this.jdbcTemplate.query(sql, rowMapper);
    }

    /**
     * 转账
     * @param outUser 汇款人
     * @param inUser 收款人
     * @param money 收款金额
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
    public void transfer(String outUser, String inUser, Double money) {
        // 收款时，收款用户的余额=现有现金+所汇金额
        this.jdbcTemplate.update("update account set balance = balance + ?" +
                "where username = ?", money, inUser);
        // 模拟系统运行时突发问题
        int i = 1 / 0;
        // 汇款时，汇款用户的余额=现有金额-所汇金额
        this.jdbcTemplate.update("update account set balance = balance - ?" +
                "where username = ?", money, outUser);
    }
}
